package com.polaris.live.ui.live.fragment.base.pager

import android.content.Context
import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
import com.polaris.live.R
import java.util.LinkedList
import java.util.Queue

/**
 * ViewPager复用适配器基类
 *
 * @author Created by lucas on 2023/11/8 09:45
 * @since 1.0.0
 */
abstract class BaseRecyclerPagerAdapter<E, VH : BaseRecyclerPagerAdapter.ViewPageHolder>(
    context: Context,
    list: MutableList<E> = ArrayList()
) : BasePagerAdapter<E>(context, list) {

    private val mViewPool = SparseArray<Queue<View>>()
    private val mHolderPool = SparseArray<VH>()

    //单击接口
    private var mOnItemClickListener: OnItemClickListener<VH>? = null

    //长按接口
    private var mOnItemLongClickListener: OnItemLongClickListener<VH>? = null

    override fun destroyItem(container: ViewGroup, position: Int, obj: Any) {
        super.destroyItem(container, position, obj)

        val holder = findHolderFormTag((obj as View)) ?: return

        val queue = mViewPool.get(holder.viewType) ?: let {
            LinkedList<View>().apply {
                mViewPool.put(holder.viewType, this)
            }
        }

        queue.offer(holder.itemView)

        mHolderPool.remove(position)
    }

    override fun instantiateItem(container: ViewGroup, position: Int): Any {
        val viewType = getViewType(position)

        val queue = mViewPool.get(viewType)

        var holder: VH? = null
        if (queue != null) {
            val view = queue.poll()
            holder = view?.let { findHolderFormTag(it) }
        }
        if (holder == null) {
            holder = onCreateViewHolder(container, viewType)
            holder.itemView.setTag(R.id.view_pager_recycler_adapter_tag, holder)
            holder.viewType = viewType
        }
        holder.position = position

        onBindViewHolder(holder, position)

        container.addView(holder.itemView)

        mHolderPool.put(position, holder)

        return holder.itemView
    }

    override fun getItemPosition(obj: Any): Int {
        return POSITION_NONE
    }

    abstract fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH

    abstract fun onBindViewHolder(holder: VH, position: Int)

    open fun getViewType(position: Int): Int {
        return 0
    }

    fun findHolderFormTag(view: View): VH? {
        val tag = view.getTag(R.id.view_pager_recycler_adapter_tag)
        return if (tag !is ViewPageHolder) {
            null
        } else {
            tag as VH
        }
    }

    /**
     * 获取指定索引的holder，有可能为空
     *
     * @param position 索引
     */
    fun findHolderFormPosition(position: Int): VH? {
        return mHolderPool.get(position)
    }

    open class ViewPageHolder(val itemView: View) {

        var viewType = 0
        var position = 0

        fun getContext(): Context {
            return itemView.context
        }
    }

    /**
     * 注册单击事件
     *
     * @param v View
     */
    fun registerClick(v: View) {
        v.setOnClickListener {
            val clickHolder = it.tag as? VH ?: return@setOnClickListener

            val position = clickHolder.position
            if (position < 0 || position >= count) {
                return@setOnClickListener
            }

            mOnItemClickListener?.onItemClick(clickHolder, it, clickHolder.position)
        }
    }

    /**
     * 注册长按事件
     *
     * @param v View
     */
    fun registerLongClick(v: View) {
        v.setOnLongClickListener {
            val clickHolder = it.tag as? VH ?: return@setOnLongClickListener false

            val position: Int = clickHolder.position
            if (position < 0 || position >= count) {
                return@setOnLongClickListener false
            }

            mOnItemLongClickListener?.onItemLongClick(clickHolder, it, clickHolder.position) ?: false
        }
    }

    fun setOnItemClickListener(listener: OnItemClickListener<VH>) {
        this.mOnItemClickListener = listener
    }

    fun interface OnItemClickListener<VH : ViewPageHolder> {

        fun onItemClick(holder: VH, v: View?, position: Int)
    }

    fun setOnItemLongClickListener(listener: OnItemLongClickListener<VH>) {
        this.mOnItemLongClickListener = listener
    }

    fun interface OnItemLongClickListener<VH : ViewPageHolder> {

        fun onItemLongClick(holder: VH, v: View, position: Int): Boolean
    }
}